//+------------------------------------------------------------------+
//|                                                       ZigZag.mq4 |
//|                   Copyright 2006-2014, MetaQuotes Software Corp. |
//|                                              http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright   "2015-2018, HandGao."
#property link        "http://www.handgao.com"
#property description "辅助信息工具"
#property version   "1.00"
#property strict

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1  Violet

//---- 指标参数
input double InpAlarmlineRatio=0.1;          // 重仓参数（该参数*杠杠=重仓）
input int    InpATRPeriod=14;                // ATR活动周期
input bool   InpShowTimeLine=false;          // 显示时间分割线
//input bool   InpShowHistoryOrder=true;      // 显示历史订单到图片   
      bool   InpShowAccountInfo=false;       // 显示账户信息
      bool   InpShowOrderInfo = false;
//---- Buffers

#define BTN_SHOW_ACCOU_INFO "BTN_SHOW_ACCOU_INFO"
#define BTN_SHOW_ORDER_INFO "BTN_SHOW_ORDER_INFO"

//+------------------------------------------------------------------+
//| mqh imports                                                      |
//+------------------------------------------------------------------+
//#include <Waltz/WaltzBackBone.mqh>
#include <Waltz/WaltzDraw.mqh>
#include <Waltz/WaltzOrder.mqh>

//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                             |
//+------------------------------------------------------------------+
int OnInit()
{
   // 启动定时器
	EventSetTimer(1);

    /*
    if(InpShowHistoryOrder){
        int nTotalOrders = OrdersHistoryTotal();      
        if(0 == nTotalOrders)
        {
            Alert("注意：当前历史订单为0");
        }
    }*/
   
	string name = BTN_SHOW_ORDER_INFO;
   /*if(ObjectFind(name))
   {
      ObjectCreate(name,OBJ_BUTTON,0,0,0);
      ObjectSet(name,OBJPROP_XDISTANCE,215);
      ObjectSet(name,OBJPROP_YDISTANCE,25);
      ObjectSet(name,OBJPROP_CORNER,CORNER_RIGHT_LOWER);
      ObjectSet(name,OBJPROP_FONTSIZE,8);
      ObjectSet(name,OBJPROP_XSIZE,60);
      ObjectSet(name,OBJPROP_YSIZE,20);
      ObjectSet(name,OBJPROP_BGCOLOR,C'30,30,30'); 
      ObjectSet(name,OBJPROP_BORDER_COLOR,C'30,30,130'); 
      ObjectSet(name,OBJPROP_SELECTABLE,false);
      ObjectSet(name, OBJPROP_COLOR, Orange);
      ObjectSetText(name,"仓位▲", 12, "Arial Black");
   }*/
   
   name = BTN_SHOW_ACCOU_INFO;
   if(ObjectFind(name))
   {
      ObjectCreate(name,OBJ_BUTTON,0,0,0);
      ObjectSet(name,OBJPROP_XDISTANCE,145);
      ObjectSet(name,OBJPROP_YDISTANCE,25);
      ObjectSet(name,OBJPROP_CORNER,CORNER_RIGHT_LOWER);
      ObjectSet(name,OBJPROP_FONTSIZE,8);
      ObjectSet(name,OBJPROP_XSIZE,60);
      ObjectSet(name,OBJPROP_YSIZE,20);
      ObjectSet(name,OBJPROP_BGCOLOR,C'30,30,30'); 
      ObjectSet(name,OBJPROP_BORDER_COLOR,C'30,30,130'); 
      ObjectSet(name,OBJPROP_SELECTABLE,false);
      ObjectSet(name, OBJPROP_COLOR, Orange);
      ObjectSetText(name,"账户▲", 12, "Arial Black");
   }
   
	return(INIT_SUCCEEDED);
}

int deinit()
{
   clearDraw();
   return(0);
}

//+------------------------------------------------------------------+
//|  每个tick跳动一次,仅用于指标,本指标从左往右计算                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,	   // 价格[] 数组的大小
				const int prev_calculated,		// 前一次调用处理的柱
				const datetime &time[],			// 时间
				const double &open[],			// 开盘价
				const double &high[],			// 最高价
				const double &low[],			   // 最低价
				const double &close[],			// 收盘价
				const long& tick_volume[],		// 订单交易量
				const long& volume[],			// 真实交易量
				const int& spread[])			   // 点差
{
   //
	static int lastBarNum = 0;
	int nDiffer = Bars-lastBarNum;
	if(nDiffer !=0)   // 出现新的k线时才处理一次，优化性能
	{
	   // 画时间分割线
        if(InpShowTimeLine)
            DrawTimeDivisionLine(lastBarNum);
        /*if(InpShowHistoryOrder)
            DrawHistoryOrderOnChar();*/
		// 
		lastBarNum = Bars;
	}
	//----
	return(rates_total);
}

//+------------------------------------------------------------------+
void OnTimer()
{
	updateLeftBottomText();
	
	createPositionCalcLine();
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| 图表事件                                                         |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
   //Event - click on the graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
      if(sparam==BTN_SHOW_ACCOU_INFO)
      {
         if(!InpShowAccountInfo)
         {
            ObjectSetText(sparam,"账户▼", 12, "Arial Black");
            InpShowAccountInfo  = true;
            DrawHistoryOrderOnChar(Symbol(),0.01,false);
         }
         else
         {
            ObjectSetText(sparam,"账户▲", 12, "Arial Black");
            InpShowAccountInfo  = false;
            clearDraw();
            for(int j=0;j<10;++j)
            {
               string name = BTN_SHOW_ACCOU_INFO + IntegerToString(j);
      			if(ObjectFind(name)>=0)
      			   ObjectDelete(name);
      		}
         }
         ObjectSet(sparam,OBJPROP_STATE,false); 
      }
      else if(sparam==BTN_SHOW_ORDER_INFO)
      {
         if(!InpShowOrderInfo)
         {
            ObjectSetText(sparam,"持仓▼", 12, "Arial Black");
            InpShowOrderInfo  = true;
         }
         else
         {
            ObjectSetText(sparam,"持仓▲", 12, "Arial Black");
            InpShowOrderInfo  = false;
         }
         ObjectSet(sparam,OBJPROP_STATE,false); 
      }
    }
    ChartRedraw();
}

// 更新左下角文字
void updateLeftBottomText()
{
   string txt = "";
   int nIndex = 0;
   if(InpShowAccountInfo)
   {
    ClearHistoryOrderOnChar();
      // ATR
   	double ATRIndexValue=iATR(Symbol(),0,InpATRPeriod,0);           //ATR 指标读数
   	string strATRIndexValue = "｜波幅：" +DoubleToString(ATRIndexValue/Point,2);
   	// 是否重仓
   	double nUsedMargin = 0.0;
   	if(AccountFreeMargin()>0.0)
   	   nUsedMargin = 100-AccountFreeMargin()/AccountBalance()*100;
   	bool isOverweight = (0 != InpAlarmlineRatio && nUsedMargin>InpAlarmlineRatio*AccountLeverage());
   	string strOverweight;
   	double nOverplus = CalculationMoneyToHands(Symbol(),(InpAlarmlineRatio*AccountLeverage()-nUsedMargin)*0.01*AccountBalance());
   	if(isOverweight)
   		strOverweight = "｜仓位：-" + DoubleToString(nUsedMargin-InpAlarmlineRatio*AccountLeverage(),2)+"%";
   	else
   		strOverweight = "｜仓位：+"+DoubleToString(nOverplus,2);
   	OrderInfo info(Symbol(),true);
   	strOverweight = "｜满仓："+DoubleToString((info.dBuyLot+info.dSellLot)*100,0)+"/"+DoubleToString(AccountBalance()*0.1,0);
      //
      int nXPos = 10;
      string sAccountMargin = "0.0";
      if(AccountMargin()>0)
         sAccountMargin = DoubleToStr(AccountEquity()/AccountMargin()*100,2);
   	// 账户余额:423.35｜账户净值:386.34｜可用保证金:315.05
   	txt = "余额:"+DoubleToStr(AccountBalance(),2)
   	   +"｜净值:"+DoubleToStr(AccountEquity(),2)
   	   +"｜可用金:"+DoubleToStr(AccountFreeMargin(),2)
   	   +"｜预付款:"+sAccountMargin+"%";
      //DrawLeftBottomText(txt,nXPos,nIndex++,Orange);
   	DrawRightTopInfo(nIndex++,txt);
   	/*
   	
   	// 总的：利润：117.01 ｜亏损：95.94 ｜赔率：1.22 ｜仓位：13/3
   	txt = "总的｜"+calcMaxStopLess(true,false);
   	createLeftBottomText(BTN_SHOW_ACCOU_INFO,txt,nXPos,nIndex++,Orange);
   	
   	// 当前：利润：100.20 ｜亏损：83.28 ｜赔率：1.20 ｜仓位：10/3
   	txt = "当前｜"+calcMaxStopLess(false,false);
   	createLeftBottomText(BTN_SHOW_ACCOU_INFO,txt,nXPos,nIndex++,Orange);
   
    // 收盘：01:01 ｜波幅：156.14 ｜仓位：-10.58%
    txt = "｜将进货量："+DoubleToStr(getMaDinLotsByAllGroupProfit(0.01,1),2);
    txt += "｜进货额："+DoubleToStr(getMaDinLotsByAllGroupProfit(0.01,1,true),2);
   	txt = "收盘："+CalculationCloseTime()+strATRIndexValue+strOverweight+txt;
   	createLeftBottomText(BTN_SHOW_ACCOU_INFO,txt,nXPos,nIndex++,Orange);
	return;
	*/
   }
}


void createPositionCalcLine()
{
   if(!InpShowOrderInfo)
   {
      int nIndex = 0;
      string objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
      ObjectDelete(objName);
      objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
      ObjectDelete(objName);
      objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
      ObjectDelete(objName);
      objName = "WA_PositionCalcLineText_"+IntegerToString(nIndex++);
      ObjectDelete(objName);
      return;
   }
   
   double dValueTop = 0.0;
   double dValueCur = 0.0;
   double dValueLow = 0.0;

   int nStart = 0;
   int nEnd = 200;
   double nValue = Ask+(200*Point);
   int nIndex = 0;
   int nColor = White;
   string objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
   if(ObjectFind(objName))
   {
      ObjectCreate(objName,OBJ_HLINE,0,iTime(Symbol(),0,nStart),nValue);
      ObjectSet(objName,OBJPROP_COLOR,nColor);
      ObjectSet(objName,OBJPROP_RAY,false);
      ObjectSet(objName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(objName,OBJPROP_WIDTH,1);
      ObjectSet(objName,OBJPROP_SELECTED,true);
   }
   dValueTop = ObjectGetDouble(0,objName,OBJPROP_PRICE);
   
   nValue = Ask;
   objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
   if(ObjectFind(objName))
   {
      ObjectCreate(objName,OBJ_HLINE,0,iTime(Symbol(),0,nStart),nValue);
      ObjectSet(objName,OBJPROP_COLOR,nColor);
      ObjectSet(objName,OBJPROP_RAY,false);
      ObjectSet(objName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(objName,OBJPROP_WIDTH,1);
      ObjectSet(objName,OBJPROP_SELECTED,true);
   }
   dValueCur = ObjectGetDouble(0,objName,OBJPROP_PRICE);
   
   nValue = Ask-(200*Point);
   objName="WA_PositionCalcLine_"+IntegerToString(nIndex++);
   if(ObjectFind(objName))
   {
      ObjectCreate(objName,OBJ_HLINE,0,iTime(Symbol(),0,nStart),nValue);
      ObjectSet(objName,OBJPROP_COLOR,nColor);
      ObjectSet(objName,OBJPROP_RAY,false);
      ObjectSet(objName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSet(objName,OBJPROP_WIDTH,1);
      ObjectSet(objName,OBJPROP_SELECTED,true);
   }
   dValueLow = ObjectGetDouble(0,objName,OBJPROP_PRICE);

   double dPositonSell = calcKellyPosition(OP_SELL,dValueCur,dValueTop,dValueLow)*AccountBalance()*0.001;
   double dPositonBuy = calcKellyPosition(OP_BUY,dValueCur,dValueLow,dValueTop)*AccountBalance()*0.001;
   string strTxt = "仓位，多："+DoubleToStr(dPositonBuy,2)+"手|空："+DoubleToStr(dPositonSell,2)+"手";
   objName = "WA_PositionCalcLineText_"+IntegerToString(nIndex++);
   if(ObjectFind(objName))
   {
      ObjectCreate(objName, OBJ_LABEL, 0, 0, 0);
      ObjectSet(objName, OBJPROP_CORNER, CORNER_LEFT_LOWER);
      ObjectSet(objName, OBJPROP_XDISTANCE, 10);
      ObjectSet(objName, OBJPROP_YDISTANCE, 20);
      ObjectSet(objName, OBJPROP_COLOR, nColor);
   }
   ObjectSetText(objName,strTxt, 12, "Arial Black");
}
